%%%-------------------------------------------------------------------
%% @doc mysqlboy public API
%% @end
%%%-------------------------------------------------------------------

-module(mysqlboy_worker).

-behaviour(gen_server).
-behaviour(poolboy_worker).
-include_lib("eunit/include/eunit.hrl").

-export([start_link/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

%%%-------------------------------------------------------------------
start_link(Args) ->
    gen_server:start_link(?MODULE, Args, []).

init(Args) ->
    process_flag(trap_exit, true),
    Hostname = proplists:get_value(hostname, Args),
    Database = proplists:get_value(database, Args),
    Username = proplists:get_value(username, Args),
    Password = proplists:get_value(password, Args),
    Conn = do_connect(Hostname, Username, Password, Database),
    {ok, Conn}.

handle_call(Request, From, Conn) ->
    try
        do_call(Request, From, Conn)
    catch
        Type:Reason:Stack ->
            ?debugFmt("handle_call error:~n"
                         " -- Request:~p, From:~p, Conn:~p~n"
                         " -- Type:~p, Reason:~p~n"
                         " -- stacktrace:~p",
                         [Request, From, Conn, Type, Reason, Stack]),
            {reply, {fail, Conn, Type, Reason}, Conn}
    end.

handle_cast(_Msg, Conn) ->
    {noreply, Conn}.

handle_info(_Info, Conn) ->
    {noreply, Conn}.

terminate(_Reason, Conn) ->
    ok = mysql:stop(Conn),
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


%% internal functions
%%%-------------------------------------------------------------------
do_connect(Hostname, Username, Password, Database) ->
    {ok, Conn} = mysql:start_link([ {host, Hostname}
                                  , {user, Username}
                                  , {password, Password}
                                  , {database, Database}
                                  , {keep_alive, true}
                                  ]),
    Conn.


%%%-------------------------------------------------------------------
do_call({query, Query, Params, FilterMap, Timeout}, _From, Conn) ->
    Result = mysql:query(Conn, Query, Params, FilterMap, Timeout),
    {reply, Result, Conn};

do_call(Request, From, Conn) ->
    ?debugFmt("mysqlboy_worker not have call Request: ~p, From: ~p.", [Request, From]),
    {reply, ok, Conn}.

